/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine - graphics/materials
// Copyright (c) 2015.  All Rights Reserved
//
// File:		AEMaterial.h
// Author:		Gianluca Belardelli
// Date:		20/07/2015
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AEMATERIAL_H_
#define _AEMATERIAL_H_

class AEBaseMesh;

#define MAX_AUXILIARY_TEXTURES    128

/// \brief
///   Material class used by the Vision engine.
///
/// An instance of this class can represent a material used for either world primitives or entity
/// models.
///
/// Use this class to obtain information about material-specific data in the Vision engine.
///
/// This class inherits the material textures it uses from the AEMaterialTextures.
///
class AEMaterial : public AEBaseObject, public AEMaterialTextures
{
// Members
public:
	/// \brief
	///   Enum that defines the effect assignment mode for materials. See AEMaterial::GetShaderMode.
	enum AEShaderMode
	{
		AESHADERMODE_AUTO     = 0,    ///< Shader selected automatically.
		AESHADERMODE_MANUAL   = 1,    ///< Shader selected manually.
		AESHADERMODE_TEMPLATE = 2     ///< Shader applied via an asset profile dependent shader assignment template.
	};

	/// \brief
	///  Flags passed to the shader provider to control automatic shader assignment.
	enum AEMaterialFlags
	{
		AEMATERIALFLAG_NONE                       = 0x00000000,   ///< No flags.
		AEMATERIALFLAG_OBJECTSPACECOORDINATES     = 0x00000001,   ///< Unused.
		AEMATERIALFLAG_VERTEXCOLOR                = 0x00000010,   ///< Select a shader that uses vertex colors.
		AEMATERIALFLAG_HASLIGHTMAPUV              = 0x00000020,   ///< The mesh has UV1 for lightmapping
		AEMATERIALFLAG_NODEFAULTSHADERS           = 0x00001000,   ///< Don't fall back to default material shaders.
		AEMATERIALFLAG_NODYNAMICLIGHTSHADERS      = 0x00002000,   ///< Don't select dynamic lighting shaders.
		AEMATERIALFLAG_TRIGGERCALLBACK_INTERNAL   = 0x10000000,   ///< Used internally, do not use.
		AEMATERIALFLAG_HASADDITIONALFORWARDPASS   = 0x20000000,   ///< Select a shader that supports additional forward passes.
		AEMATERIALFLAG_DEFAULT                    = AEMATERIALFLAG_HASLIGHTMAPUV ///< Default flags set at construction time (by default we assume UV1 is supported)
	};

	/// \brief
	///   Topology of the geometry referencing this material.
	enum AEGeometryTopology
	{
		AEGEOMTOPOLOGY_3DMESH = 0,                 ///< 3D mesh that refers to this material contains positions that can be straightly multiplied with MVP matrix in vertex shader.
		AEGEOMTOPOLOGY_TERRAINMESH,                ///< Similar to AEGEOMTOPOLOGY_3DMesh, but a terrain mesh is referencing to this material.
		AEGEOMTOPOLOGY_BILLBOARD,                  ///< Billboard which needs special handling in vertex shader: POSITION=center, COLOR=RGBA color, TEXCOORD0=UVs, TEXCOORD1=stretch x/y.
		AEGEOMTOPOLOGY_BILLBOARDVERTICALALIGNED,   ///< Similar to AEGEOMTOPOLOGY_Billboard, but the billboard is vertically aligned.

		AEGEOMTOPOLOGY_FIRSTCUSTOM = 100           ///< First slot that can be used for custom topologies.
	};

/*	AECompiledEffectPtr 	m_spCurrentEffect;
	AECompiledTechniquePtr m_spCurrentTechnique;
	AECompiledTechniquePtr m_spDynPointLight;
	AECompiledTechniquePtr m_spDynSpotLight;
	AECompiledTechniquePtr m_spDynProjPointLight;
	AECompiledTechniquePtr m_spDynDirectionalLight;

	AECompiledTechniquePtr m_spDynPointLightShadow;
	AECompiledTechniquePtr m_spDynSpotLightShadow;
	AECompiledTechniquePtr m_spDynProjPointLightShadow;
	AECompiledTechniquePtr m_spDynDirectionalLightShadow;

	AECompiledTechniquePtr m_spShadowmapFill;

	AECompiledTechniquePtr m_spMirror;
	AECompiledTechniquePtr m_spMirrorSimple;
	AECompiledTechniquePtr m_spDepthFill;

	AECompiledTechniquePtr m_spCustomTechniques[8];
*/
private:
	char		*m_lpName;
	AEBaseMesh 	*m_lpOwnerMesh;       ///< pointer to the base mesh that refers to this material

	AEINT32		m_nMaterialFlags;        ///< casted to AEMaterialFlags (combinable)
	AEColor 	m_crAmbientColor;      ///< the ambient color of this material

	AEUINT8 	m_uiTransparencyType; 			///< casted to AETransparencyType
	AEUINT8 	m_uiSortingKey;          ///< internal sorting key; has to be in the range 0..15
	AEUINT8 	m_uiLightingMethod; 	      ///< casted to AELightingMethod
	AEUINT8 	m_uiDeferredID;          ///< material ID that is written to G-Buffer in deferred rendering

	AEBOOL32 	m_bCastStaticShadows;
	AEUINT8 	m_uiPassType; ///< casted to AEPassType with VPT_Undefined=AUTO
	AEUINT8 	m_uiResolvedPassType; ///< casted to AEPassType, automatically detected pass type using force, transparency and shader settings
	AEBOOL32 	m_bDoubleSided;
	AEBOOL32 	m_bDepthWrite;
	AEBOOL32 	m_bSavePathsDataDirectoryRelative;
	AEUINT8 	m_uiGeometryTopology;    ///< casted to AEGeometryTopology
	AEUINT8 	m_uiClampUV;              ///< V_BIT(0) and/or V_BIT(1) for clamping in u and v direction

	AEFLOAT32 	m_fSpecMul;     ///<specular multiplier
	AEFLOAT32 	m_fSpecExp;     ///<specular exponent
	AEFLOAT32 	m_fParallaxScale;  ///< parallax scale
	AEFLOAT32 	m_fParallaxBias;   ///< parallax bias
	AEFLOAT32 	m_fCustomAlphaThreshold; ///< custom alpha threshold; in case it is lower than 0, global alpha threshold is taken
	AEFLOAT32 	m_fDepthBias;            ///< z-offset value that is passed to the shader
	AEFLOAT32 	m_fDepthBiasClamp;       ///< clamped z-offset value that is passed to the shader
	AEFLOAT32 	m_fSlopeScaledDepthBias; ///< slope dependent z-offset value that is passed to the shader

	AEINT32 	m_nUserFlags;              ///< customizable user flags
	AEINT32 	m_nReferencedByOthers;     ///< how often this material is referenced by other materials

	AEShaderMode m_eShaderMode;   ///< whether shader assignment is performed automatically or manually
	AEMaterial	*m_lpOverrideMaterial;        ///< Dumb Pointer to the Material that overrides this one. Can be AENULL.

// Methods
private:
	// non-copyable (using standard operators)
	AEMaterial( const AEMaterial &refMaterial );
	AEMaterial &operator=( const AEMaterial &refMaterial );

	/// \brief Increases the internal counter of how often this material is referenced by other materials.
	AE_FORCEINLINE void addReferenceByOtherSurface( void );

	/// \brief Decreases the internal counter of how often this material is referenced by other materials.
	AE_FORCEINLINE void removeReferenceByOtherSurface( void );

	/// \brief Copies the attributes from the passed material to this (except for the material override properties).
	void copyFromInternal( const AEMaterial &refOther );

public:
	/// \brief Constructor.
	AE_DLLIMPEXP AEMaterial( void );

	/// \brief Destructor.
	AE_DLLIMPEXP virtual ~AEMaterial( void );

	/// \brief
	///   Returns true if both materials equal each other.
	AE_DLLIMPEXP AEBOOL32 Equals( AEMaterial *lpOtherMaterial ) const;

	/// \brief
	///   Sets all smart pointers to AENULL so this material does not hold any references anymore.
	AE_DLLIMPEXP void ClearReferences( void );

	/** @name Material Name */
	/// @{
	/// \brief
	///   Returns the material name.
	AE_FORCEINLINE const char *GetName( void ) const;

	/// \brief
	///   Sets the name of this material.
	AE_FORCEINLINE void SetName( const char *lpNewString );

	/// @}
	/// @name User Data
	/// @{
	/// \brief
	///   Returns the user data string set in editing tools (e.g. vEdit, Maya). If not set, the return value is AENULL.
	//AE_FORCEINLINE const char *GetEditorUserDataString( void ) const;

	/// \brief
	///   Sets a new user data string.
	//AE_FORCEINLINE void SetEditorUserDataString( const char *lpNewString );

	/// @}
	/** @name Material Properties */
	/// @{
	/// \brief
	///   Returns the transparency type of the material.
	///
	/// \return
	///   AETransparencyType: The transparency type of the material
	///
	/// \sa AETransparencyType
	AE_FORCEINLINE AETransparencyType GetTransparencyType( void ) const;

	/// \brief
	///   Sets the transparency type of the material.
	AE_FORCEINLINE void SetTransparencyType( AETransparencyType ttType );

	/// \brief
	///   Returns whether the material is translucent, i.e. it uses a blend mode other than AETRANSPTYPE_NONE or AETRANSPTYPE_ALPHATEST.
	AE_FORCEINLINE AEBOOL32 IsTranslucent( void ) const;

	/// \brief
	///   Returns whether the material is light-mapped. First, the lighting method must be set to VIS_LIGHTING_LIGHTMAPPING and secondly a lightmap UV stream must be provided by the owner mesh (AEMATERIALFLAG_HasLightmapUV nFlag)
	AE_DLLIMPEXP AEBOOL32 IsLightMapped( void ) const;

	/// \brief
	///   Determines whether this material satisfies a few properties required to support lightmapping.
	///
	/// In case the material is loaded by a mesh, this status includes support for the UV1 stream. In other cases (e.g. when loaded from a material lib) this cannot be considered and the function returns true
	AE_DLLIMPEXP AEBOOL32 IsLightmappingSupported( void ) const;

	/// \brief
	///   Returns whether the material is double-sided.
	///
	/// No backface culling will be performed for primitives using a double-sided material.
	///
	/// \return
	///   AEBOOL32: true if the material is double-sided
	AE_FORCEINLINE AEBOOL32 IsDoubleSided( void ) const;

	/// \brief
	///   Sets whether the material is double-sided.
	AE_FORCEINLINE void SetDoubleSided( AEBOOL32 bDoubleSided );

	/// \brief
	///   Determines whether the default shader of this material supports depth writing.
	AE_FORCEINLINE AEBOOL32 IsDepthWriteEnabled( void ) const;

	/// \brief
	///   Determines whether the default shader of this material uses texture clamping. The return value is a mask of 2 bits (bit#0 = clamp in U direction, bit#1=v direction)
	AE_FORCEINLINE AEUINT8 GetTextureClampingMask( void ) const;

	/// \brief
	///   Returns the pass type assigned by the material provider.
	///
	/// \return
	///   The pass type.
	///
	/// The default is VPT_AUTO, which means the shader provider uses information such as depth write and transparency settings to determine the effective pass type.
	AE_FORCEINLINE AEPassType GetPassType( void ) const;

	/// \brief
	///   Sets a new pass type. A mode other than VPT_AUTO (default) enforces the material shader to use the given pass type regardless of depth write nFlag or transparency mode.
	AE_FORCEINLINE void SetPassType( AEPassType eType );

	/// \brief
	///   Returns the automatically resolved pass type. When a pass type is forced on the material, that one is used. Otherwise the pass type from the shader is used.
	///   If there is no pass type set on the shader, the transparency settings are used to determine the pass type
	AE_FORCEINLINE AEPassType GetResolvedPassType( void ) const;

	/// \brief
	///   Sets whether the default shader of this material will use depth writing.
	AE_FORCEINLINE void SetDepthWriteEnabled( AEBOOL32 bEnable );

	/// \brief
	///   Sets whether the default shader of this material will use texture clamping.
	AE_FORCEINLINE void SetUseTextureClamping( AEBOOL32 bClampU, AEBOOL32 bClampV );

	/// \brief
	///   Returns the z-offset value that is passed to the shader.
	AE_FORCEINLINE AEFLOAT32 GetDepthBias( void ) const;

	/// \brief
	///   Sets the z-offset value that is passed to the shader.
	AE_FORCEINLINE void SetDepthBias( AEFLOAT32 fBias );

	/// \brief
	///   Returns the z-offset clamping value that is passed to the shader.
	AE_FORCEINLINE AEFLOAT32 GetDepthBiasClamp( void ) const;

	/// \brief
	///   Sets the z-offset clamping value that is passed to the shader.
	AE_FORCEINLINE void SetDepthBiasClamp( AEFLOAT32 fBiasClamp );

	/// \brief
	///   Returns the slope dependent z-offset value that is passed to the shader.
	AE_FORCEINLINE AEFLOAT32 GetSlopeScaledDepthBias( void ) const;

	/// \brief
	///   Sets the slope dependent z-offset value that is passed to the shader.
	AE_FORCEINLINE void SetSlopeScaledDepthBias( AEFLOAT32 fScaledBias );

	/// \brief
	///   Returns the topology of the geometry referencing this material.
	///
	/// \see AEMaterialTextures::AEGeometryTopology
	AE_FORCEINLINE AEGeometryTopology GetGeometryTopology( void ) const;

	/// \brief
	///   Sets the geometry topology.
	///
	/// \param eType
	///   Geometry topology of the geometry referencing this material.
	///
	/// \see AEMaterialTextures::AEGeometryTopology
	AE_FORCEINLINE void SetGeometryTopology( AEGeometryTopology eType );

	/// \brief
	///   Returns whether the material is fullbright.
	///
	/// Fullbright materials are not affected by any lighting.
	///
	/// \return
	///   AEBOOL32: true if the material is fullbright.
	AE_FORCEINLINE AEBOOL32 IsFullbright( void ) const;

	/// \brief
	///   Returns the ambient color of the material.
	AE_FORCEINLINE AEColor GetAmbientColor( void ) const;

	/// \brief
	///   Sets the ambient color of the material.
	AE_FORCEINLINE void SetAmbientColor( const AEColor &refColor );

	/// \brief
	///   Returns the specular multiplier.
	///
	/// A return value of 0.0 means that the material does not have specularity.
	///
	/// \return
	///   AEFLOAT32 : The specular multiplier
	AE_FORCEINLINE AEFLOAT32 GetSpecularMultiplier( void ) const;

	/// \brief
	///   Sets the specular multiplier.
	AE_FORCEINLINE void SetSpecularMultiplier( AEFLOAT32 fMultiplier );

	/// \brief
	///   Returns the specular exponent.
	///
	/// A return value of 0.0 means that the material does not have specularity.
	///
	/// \return
	///   AEFLOAT32 : The specular exponent
	AE_FORCEINLINE AEFLOAT32 GetSpecularExponent( void ) const;

	/// \brief
	///   Sets the specular exponent.
	/// \param f The new specular exponent.
	AE_FORCEINLINE void SetSpecularExponent( AEFLOAT32 fExponent );

	/// \brief
	///   Returns the alpha test threshold value [0..1] of this material.
	///
	/// If the m_fCustomAlphaThreshold member of this material is left to default -1 then this
	/// function returns the global alpha threshold.
	///
	/// The global alpha test threshold value is defined via
	/// VisRenderer_cl::SetGlobalAlphaTestThreshold.
	AE_DLLIMPEXP AEFLOAT32 GetAlphaTestThreshold( void ) const;

	/// \brief
	///   Sets the alpha test threshold value [0..1] of this material.
	///
	/// \param fAlphaThreshold
	///   The new alpha test threshold.
	///
	/// \sa GetAlphaTestThreshold
	AE_FORCEINLINE void  SetAlphaTestThreshold( AEFLOAT32 fAlphaThreshold );

	/// \brief Sets the static mesh pointer of this resource.
	AE_FORCEINLINE void SetMesh( AEBaseMesh *lpMesh );

	/// \brief Returns the static mesh pointer of this resource.
	AE_FORCEINLINE AEBaseMesh *GetMesh( void ) const;

	/// \brief
	///   Sets the internal sorting key (does not trigger re-sorting).
	AE_FORCEINLINE void SetSortingKey( AEUINT8 uiKey );

	/// \brief
	///   Returns the sorting key for this material.
	AE_FORCEINLINE AEUINT8 GetSortingKey( void ) const;

	/// \brief
	///   Returns whether submeshes with this material should cast static shadows.
	AE_FORCEINLINE AEBOOL32 GetCastStaticShadows( void ) const;

	/// \brief
	///   Sets whether submeshes with this material should cast static shadows.
	AE_FORCEINLINE void SetCastStaticShadows( AEBOOL32 bEnable );

	/// \brief
	///   Sets all material flags.
	///
	/// \param Flags
	///  The new material flags.
	///
	/// \sa AEMaterialFlags
	AE_FORCEINLINE void SetMaterialFlags( AEINT32 nFlags );

	/// \brief
	///   Returns whether some material nFlag is set.
	///
	/// \param nFlag
	///  The material nFlag to test.
	///
	/// \sa AEMaterialFlags
	AE_FORCEINLINE AEBOOL32 IsMaterialFlagSet( AEINT32 nFlag ) const;

	/// \brief
	///   Raises some material nFlag.
	///
	/// \param nFlag
	///  The material nFlag to raise.
	///
	/// \sa AEMaterialFlags
	AE_FORCEINLINE void RaiseMaterialFlag( AEINT32 nFlag );

	/// \brief
	///   Clears some material nFlag.
	///
	/// \param nFlag
	///  The material nFlag to clear.
	///
	/// \sa AEMaterialFlags
	AE_FORCEINLINE void ClearMaterialFlag( AEINT32 nFlag );

	/// \brief
	///   Sets all user flags.
	AE_FORCEINLINE void SetUserFlags( AEINT32 nFlags );

	/// \brief
	///   Returns all user flags.
	AE_FORCEINLINE AEINT32 GetUserFlags( void ) const;

	/// \brief
	///   Returns whether some user nFlag is set.
	AE_FORCEINLINE AEBOOL32 IsUserFlagSet( AEINT32 nFlag ) const;

	/// \brief
	///   Raises some user nFlag.
	AE_FORCEINLINE void RaiseUserFlag( AEINT32 nFlag );

	/// \brief
	///   Clears some user nFlag.
	AE_FORCEINLINE void ClearUserFlag( AEINT32 nFlag );

	/// \brief
	///   Returns the deferred ID of this material.
	AE_FORCEINLINE AEUINT8 GetDeferredID( void ) const;

	/// \brief
	///   Sets the deferred ID of this material.
	AE_FORCEINLINE void SetDeferredID( AEUINT8 uiId );

	/// \brief
	///   Returns the parallax scale value.
	AE_FORCEINLINE AEFLOAT32 GetParallaxScale( void ) const;

	/// \brief
	///   Sets the parallax scale value.
	AE_FORCEINLINE void SetParallaxScale( AEFLOAT32 fScale );

	/// \brief
	///   Returns the parallax bias value.
	AE_FORCEINLINE AEFLOAT32 GetParallaxBias( void ) const;

	/// \brief
	///   Sets the parallax bias value.
	AE_FORCEINLINE void SetParallaxBias( AEFLOAT32 fBias );

	/// @}
	/** @name Shader Effect Related */
	/// @{
	/// \brief
	///   Sets the technique to be used for rendering this material. Use AEMaterial::SetEffect instead.
	//AE_DLLIMPEXP void SetTechnique( AECompiledTechnique *lpTech );

	/// \brief
	///   Provided for backwards compatibility. Internally calls the current shader provider's SetEffect() function.
	//AE_DLLIMPEXP void SetEffect( AECompiledEffect *lpFX, AETechniqueConfig *lpDefaultConfig = AENULL );

	/// \brief
	///   Changes the current shader to the one provided by the given material template for the current asset profile.
	///
	/// This function will also set the shader mode to AESHADERMODE_Template and lets the shader provider update the shader assignments.
	/// If szMaterialTemplatePath is AENULL, the template will be removed and the shader mode is set to AESHADERMODE_AUTO.
	///
	/// \param szMaterialTemplatePath
	///   The path to the material template (.vmtx) file.
	///
	/// \return
	///  True if the template was loaded successfully.
	AE_DLLIMPEXP AEBOOL32 SetMaterialTemplate( const char *lpMaterialTemplatePath );

	/// \brief
	///   Returns the currently set material template.
	//AE_DLLIMPEXP const VMaterialTemplateResource *GetMaterialTemplate( void );

	/// \brief
	///   Returns the correct shader effect instance. This can be the default effect or the custom
	///   effect assignment assigned using SetEffect.
	//AE_DLLIMPEXP AECompiledEffect *GetEffect( void ) const;

	/// \brief
	///   Returns the shader technique for this material.
	//AE_DLLIMPEXP AECompiledTechnique *GetTechnique( void ) const;

	/// \brief
	///   Used internally to set AESHADERMODE_Auto vs. AESHADERMODE_Manual vs. AESHADERMODE_Template mode.
	AE_FORCEINLINE void SetShaderMode( AEShaderMode eShaderMode );

	/// \brief
	///   Returns the current shader effect mode. Can be AESHADERMODE_Auto, AESHADERMODE_Manual or AESHADERMODE_Template.
	///
	/// materials marked as AESHADERMODE_Auto will always get the appropriate material effect
	/// assigned by the shader provider class (IVisShaderProvider_cl).
	///
	/// When manually assigning a shader effect, the material will be marked as AESHADERMODE_Manual and when
	/// choosing the shader via a template the material will be marked as AESHADERMODE_Template.
	///
	/// Only shader assignments of type AESHADERMODE_Manual are saved into the shader assignment
	/// file (world and models)
	AE_FORCEINLINE AEShaderMode GetShaderMode( void ) const;

	/// \brief
	///   Reapplies the material shader assignment. This is needed for example if the shader provider changed.
	///
	/// \param bIncludeManualAssignments
	///    If true, manual shader assignments are reapplied via the shader provider.
	/// \param iFlags
	///    These flags (AEMaterialFlags) are passed to the shader provider to influence the automatic shader assignment.
	AE_DLLIMPEXP void ReapplyShader( AEBOOL32 bIncludeManualAssignments, AEINT32 nFlags = AEMATERIALFLAG_NONE);

	/// \brief
	///   Returns the lighting mode of this material. To test whether lightmapping should be used as a shader technique, rather use function IsLightmapped.
	AE_FORCEINLINE AELightingMethod GetLightingMode( void ) const;

	/// \brief
	///   Sets the lighting mode of this material.
	///
	/// \param mode
	///   The new lighting mode.
	///
	/// \sa AELightingMethod
	AE_FORCEINLINE void SetLightingMode( AELightingMethod lmMode );

	/// @}

	AE_DLLIMPEXP void CopyFrom( const AEMaterial &refOther );

	/// \brief
	///   While the regular CopyFrom method just copies the material override along,
	///   this version of the copy method either resolves the override (when bResolveOverrides is true)
	///   and copies the material that is referenced in the override instead of the one directly passed,
	///   or it ignores the override if bResolveOverrides is false.
	///   Currently this method is used as a helper to create material libraries, if you want an identical
	///   copy of a material, please use the regular CopyFrom method.
	///
	/// \param other
	///    The material to copy from.
	///
	/// \param bResolveOverrides
	///    If true, material overrides will be resolved (the material is copied from the override instead).
	///    If false, material overrides will be ignored (will be set to AENULL on this material).
	AE_DLLIMPEXP void CopyFromAndHandleOverrides( const AEMaterial &refOther, AEBOOL32 bResolveOverrides );

	AE_DLLIMPEXP void CopyLightTechniques( const AEMaterial &refOther );
	AE_DLLIMPEXP void DeleteSurfaceData( void );
	AE_DLLIMPEXP void OnCreated( AEBOOL32 bTriggerCallback=true );
	AE_DLLIMPEXP void OnDestroyed( void );
	AE_DLLIMPEXP AEINT32 Compare( const AEMaterial &refOther ); ///< used for material sorting

	/// \brief Returns how often this material is referenced by other materials.
	AE_FORCEINLINE AEINT32 GetOtherSurfaceReferenceCounter( void ) const;

	/// \brief Resolves the pass type and stores the result internally.
	AE_DLLIMPEXP void ResolvePassType( void );

	/// \brief
	///   Resolves the pass type with a given shader override and returns the result.
	///
	/// \param pShader
	///   The shader that should be used. If AENULL, the internal shader will be used.
	///
	/// \return
	///   The resolved pass type.
	AE_DLLIMPEXP AEUINT8 ResolvePassType( const AECompiledShaderPass *lpShader ) const;

	/// \brief
	/// Returns the path of the MaterialLibrary that should override this material.
	AE_DLLIMPEXP const char *GetOverrideLibraryName( void ) const;

	/// \brief
	/// Returns the name of the material that should override this material.
	AE_DLLIMPEXP const char *GetOverrideMaterialName( void ) const;

	/// \brief
	/// Sets the path of the MaterialLibrary and the name of the material that should override this material.
	AE_DLLIMPEXP AEBOOL32 SetMaterialOverride( AEBOOL32 bUpdateInstances, const char *lpLibraryFileName, const char *lpMaterial = AENULL );

	/// \brief
	///   Returns a pointer to the override material of this material, or this if no override material is used.
	AE_DLLIMPEXP AEMaterial *GetOverrideMaterial( void );
};

#include "AEMaterial.inl"

#endif // _AEMATERIAL_H_
